#include <gmlib/err.h>
#include <gmlib/stream/zuc.h>
#include <memory.h>
#include <stdlib.h>

static uint8_t IK1[16] = {0};
static uint32_t COUNT1 = 0;
static uint8_t BEARER1 = 0;
static uint8_t DIRECTION1 = 0;
static uint8_t M1[] = {0, 0, 0, 0};
static int LENGTH1 = 0x1;
static uint8_t MAC1[4] = {0xC8, 0xA9, 0x59, 0x5E};

static uint8_t IK2[16] = {
    0xC9, 0xE6, 0xCE, 0xC4, 0x60, 0x7C, 0x72, 0xDB,
    0x00, 0x0A, 0xEF, 0xA8, 0x83, 0x85, 0xAB, 0x0A,
};
static uint32_t COUNT2 = 0xA94059DA;
static uint8_t BEARER2 = 0xA;
static uint8_t DIRECTION2 = 1;
static uint8_t M2[] = {
    0x98, 0x3B, 0x41, 0xD4, 0x7D, 0x78, 0x0C, 0x9E,  //
    0x1A, 0xD1, 0x1D, 0x7E, 0xB7, 0x03, 0x91, 0xB1,  //
    0xDE, 0x0B, 0x35, 0xDA, 0x2D, 0xC6, 0x2F, 0x83,  //
    0xE7, 0xB7, 0x8D, 0x63, 0x06, 0xCA, 0x0E, 0xA0,  //
    0x7E, 0x94, 0x1B, 0x7B, 0xE9, 0x13, 0x48, 0xF9,  //
    0xFC, 0xB1, 0x70, 0xE2, 0x21, 0x7F, 0xEC, 0xD9,  //
    0x7F, 0x9F, 0x68, 0xAD, 0xB1, 0x6E, 0x5D, 0x7D,  //
    0x21, 0xE5, 0x69, 0xD2, 0x80, 0xED, 0x77, 0x5C,  //
    0xEB, 0xDE, 0x3F, 0x40, 0x93, 0xC5, 0x38, 0x81,  //
    0x00, 0x00, 0x00, 0x00,
};
static int LENGTH2 = 0x241;
static uint8_t MAC2[4] = {0xFA, 0xE8, 0xFF, 0x0B};

static uint8_t out[4];

void test_zuc_mac() {
    zuc_integrity_mac(out, M1, LENGTH1, COUNT1, BEARER1, DIRECTION1, IK1);
    if (memcmp(out, MAC1, ZUC_MAC_SIZE) != 0) {
        ERR_LOG("Err in zuc_mac");
        goto error;
    }

    zuc_integrity_mac(out, M2, LENGTH2, COUNT2, BEARER2, DIRECTION2, IK2);
    if (memcmp(out, MAC2, ZUC_MAC_SIZE) != 0) {
        ERR_LOG("Err in zuc_mac");
        goto error;
    }

    return;
error:
    exit(-1);
}
